package com.ice.framework.openfeign.decoder;

import com.ice.framework.common.base.ResponseResult;
import com.ice.framework.common.exception.CommonException;
import feign.FeignException;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @author wangwei
 * @Date 2022/10/27 10:14
 */
public class ResponseResultDecoder implements Decoder {

    private final SpringDecoder decoder;

    public ResponseResultDecoder(SpringDecoder decoder) {
        this.decoder = decoder;
    }

    @Override
    public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
        Method method = response.request().requestTemplate().methodMetadata().method();
        Class<?> returnType = method.getReturnType();
        if (returnType != ResponseResult.class) {
            Type newType = new ParameterizedType() {
                @Override
                public Type[] getActualTypeArguments() {
                    return new Type[]{type};
                }

                @Override
                public Type getRawType() {
                    return ResponseResult.class;
                }

                @Override
                public Type getOwnerType() {
                    return null;
                }
            };
            ResponseResult<?> result = (ResponseResult<?>) this.decoder.decode(response, newType);
            // 业务异常处理
            processCommonException(result);
            //只返回data
            return result.getData();
        }
        return this.decoder.decode(response, type);
    }

    /**
     * 处理openfeign 返回异常
     * @Author wangwei
     * @Date 2022/10/27
     */
    private void processCommonException(ResponseResult<?> result) {
        if (result.getSuccess()) {
            return;
        }
        throw new CommonException(result.getErrorCode(), result.getErrorMsg());
    }
}
